﻿using org.xisoft.game.utils;
using org.xisoft.game.utils.game;
using org.xisoft.game.utils.game.algorithms;
using ReversiModule.Chess;
using ReversiModule.Chess.Algorithms;
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

namespace ReversiModule
{
    public class ReversiBoardPanel : BlockBroadControl
    {
        private ReversiBoard broad;
        private AiAlgorithm aiAlgorithm;

        public override string Name => "黑白棋";

        public ReversiBoardPanel() : base(ReversiBoard.MAXX, ReversiBoard.MAXY )
        {
            broad = new ReversiBoard();
            aiAlgorithm = new MulThreadAlgorithm<AiAlgorithm>();
            //aiAlgorithm = new AlphaBetaAlgorithm();

        }



        private void DoAfterMove(MoveAction moveAction)
        {
            HideLoading();

            if (moveAction != null)
                aiAlgorithm.DoNext(broad, moveAction);


            bool? winColor = aiAlgorithm.GetWinColor(broad);

            if (moveAction == null || winColor.HasValue)
            {
                
                if (winColor.Value)
                    MessageBox.Show("you win" );
                else
                    MessageBox.Show("you lost" );
            }
            Invalidate();
        }

        protected override void OnClick(int selectX, int selectY)
        {

            if (!aiAlgorithm.CanMove(broad, selectX, selectY))
            {
                MessageBox.Show("这里不能下");
                return;
            }
            MoveAction moveAction = new MoveAction { ToX = selectX, ToY = selectY };
            aiAlgorithm.DoNext(broad,moveAction);
            bool? winColor = aiAlgorithm.GetWinColor(broad);

            if (moveAction == null || winColor.HasValue)
            {

                if (winColor.Value)
                    MessageBox.Show("you win");
                else
                    MessageBox.Show("you lost");
            }
            Invalidate();
            ShowLoading();

            ReversiBoard b = broad.Clone() as ReversiBoard;

            AsyncTask<ReversiBoard,MoveAction> task = new AsyncTask<ReversiBoard,MoveAction>(this.ChessBoardControl, DoAfterMove);
            task.Start(aiAlgorithm.Search,b);

          
        }

        protected override void DrawItems(Graphics g, Rectangle rect)
        {
            base.DrawItems(g, rect);

            int maxIndexX = 0;
            int maxIndexY = 0;
            int maxIndex = 0;

            for (int i = 0; i < MaxX - 1; i++)
                for (int j = 0; j < MaxY - 1; j++)
                {
                    ChessItem item = broad[i, j];
                    if (item == null) continue;
                    DrawItem(g, item.IsBlack ?  blackItemBrush: writeItemBrush, i, j, item.DisplayName);
                    if (maxIndex < item.Index)
                    {
                        maxIndex = item.Index;
                        maxIndexX = i;
                        maxIndexY = j;
                    }
                }

            int orginLeft = maxIndexX * GridItemWidth + Rect.Left;
            int orginTop = maxIndexY * GridItemHeight + Rect.Top;
            int left = orginLeft + (GridItemWidth - ItemWidth) / 2;
            int top = orginTop + (GridItemHeight - ItemHeight) / 2;
            for (int i = 2; i < 14; i += 4)
                g.DrawEllipse(selectedItemPen, left-i/2 , top-i/2 , ItemWidth + i, ItemHeight + i);

            //提示
            /*List<MoveAction> list = aiAlgorithm.GetAllCanMoves(broad);
            foreach (MoveAction moveAction in list)
                DrawItem(g, Brushes.LightPink, moveAction.X, moveAction.Y, moveAction.Score.ToString());
            */
        }

        private void DrawItem(Graphics g, Brush brush, int x, int y, String text)
        {
            int orginLeft = x * GridItemWidth + Rect.Left;
            int orginTop = y * GridItemHeight + Rect.Top;
            int left = orginLeft + (GridItemWidth - ItemWidth) / 2;
            int top = orginTop + (GridItemHeight - ItemHeight) / 2;


            g.FillEllipse(brush, left, top, ItemWidth, ItemHeight);

            SizeF sizef = g.MeasureString(text, Font);

            left = orginLeft + (int)Math.Round((GridItemWidth - sizef.Width) / 2, MidpointRounding.AwayFromZero);
            top = orginTop + (int)Math.Round((GridItemHeight - sizef.Height) / 2, MidpointRounding.AwayFromZero);

            g.DrawString(text, Font, broadFontBrush, left, top);
        }

        public override void Read(BinaryReader br)
        {
            broad.Read(br);
        }

        public override void Save(BinaryWriter bw)
        {
            broad.Save(bw);
        }

        public override void Undo()
        {
            broad.Undo();
        }
    }
}
